package com.gzceb.zhgjj.security.dao;

// default package

import java.util.HashMap;
import java.util.List;

import org.hibernate.LockMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.gzceb.zhgjj.security.dao.SysAuthoritiesDAO;
import com.gzceb.zhgjj.security.dao.SysRolesAuthoritiesDAO;
import com.gzceb.zhgjj.security.dao.SysUsersRolesDAO;

import com.gzceb.zhgjj.security.entity.SysAuthorities;
import com.gzceb.zhgjj.security.entity.SysRolesAuthorities;

import com.gzceb.zhgjj.security.entity.SysRoles;
import com.gzceb.zhgjj.util.Utils;

/**
 * A data access object (DAO) providing persistence and search support for
 * SysRoles entities. Transaction control of the save(), update() and delete()
 * operations can directly support Spring container-managed transactions or they
 * can be augmented to handle user-managed Spring transactions. Each of these
 * methods provides additional information for how to configure it for the
 * desired type of transaction control.
 * 
 * @see .SysRoles
 * @author MyEclipse Persistence Tools
 */

public class SysRolesDAO extends HibernateDaoSupport {
	private static final Logger log = LoggerFactory
			.getLogger(SysRolesDAO.class);
	// property constants
	public static final String ROLE_NAME = "roleName";
	public static final String ROLE_DESC = "roleDesc";
	public static final String ENABLED = "enabled";
	public static final String ISSYS = "issys";
	public static final String MODULE = "module";

	// 权限dao
	private SysAuthoritiesDAO sysAuthoritiesDao;

	// 角色和权限的对应关系的dao
	private SysRolesAuthoritiesDAO sysRolesAuthoritiesDao;

	// 用户和角色对应关系的dao
	private SysUsersRolesDAO sysUsersRolesDao;

	protected void initDao() {
		// do nothing
	}

	// 注入
	public void setSysAuthoritiesDAO(SysAuthoritiesDAO sysAuthoritiesDao) {
		this.sysAuthoritiesDao = sysAuthoritiesDao;
	}

	public SysAuthoritiesDAO getSysAuthoritiesDAO() {
		return sysAuthoritiesDao;
	}

	public void setSysRolesAuthoritiesDAO(
			SysRolesAuthoritiesDAO sysRolesAuthoritiesDao) {
		this.sysRolesAuthoritiesDao = sysRolesAuthoritiesDao;
	}

	public SysRolesAuthoritiesDAO getSysRolesAuthoritiesDAO() {
		return sysRolesAuthoritiesDao;
	}

	public SysUsersRolesDAO getSysUsersRolesDAO() {
		return sysUsersRolesDao;
	}

	public void setSysUsersRolesDAO(SysUsersRolesDAO sysUsersRolesDao) {
		this.sysUsersRolesDao = sysUsersRolesDao;
	}

	/*
	 * 将从页面返回的角色对象进行保存。
	 */
	public void persist(SysRoles transientInstance) {

		log.debug("角色 " + transientInstance.getRoleName() + " 持久化!");

		try {

			// 为写入的角色设置唯一id
			transientInstance.setRoleId(Utils.getPkId() + "");

			String roleName = transientInstance.getRoleName();

			// 当角色标识前缀不为"ROLE_"时，要添加该标识。
			if (roleName.startsWith("ROLE")) {

				if (!roleName.startsWith("ROLE_")) {
					roleName = roleName.substring(0, 4) + "_"
							+ roleName.substring(4);
					transientInstance.setRoleName(roleName);
				}

			} else {
				transientInstance.setRoleName("ROLE_" + roleName);
			}

			// 持久化
			getHibernateTemplate().persist(transientInstance);

			log.debug("角色 " + transientInstance.getRoleName() + " 持久化成功！");

		} catch (RuntimeException re) {

			log.error("角色 " + transientInstance.getRoleName() + " 持久化失败！", re);
			throw re;

		}
	}

	public void save(SysRoles transientInstance) {
		log.debug("saving SysRoles instance");
		try {
			getHibernateTemplate().save(transientInstance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	public void delete(SysRoles persistentInstance) {
		log.debug("deleting SysRoles instance");
		try {
			getHibernateTemplate().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	/**
	 * 根据角色id删除该角色。
	 * 
	 * @author
	 * @param roleId
	 */
	public void delete(String roleId) {
		log.debug("根据角色id删除该角色！角色id为 ： " + roleId);
		try {

			SysRoles role = findById(roleId);

			getHibernateTemplate().delete(role);

			log.debug("角色id" + roleId + "删除成功！");
		} catch (RuntimeException re) {
			log.error("角色id" + roleId + "删除失败！", re);
			throw re;
		}
	}

	public SysRoles findById(java.lang.String id) {
		log.debug("getting SysRoles instance with id: " + id);
		try {
			SysRoles instance = (SysRoles) getHibernateTemplate().get(
					"SysRoles", id);
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	/**
	 * 根据平台中的子系统返回角色列表。
	 * 
	 * @author
	 * @return SysRoles 列表
	 */
	public List<SysRoles> findRolesLst(String xtmk) {
		try {

			String hql = "";

			// 若xtmk为空，则返回所有角色列表。
			if (null == xtmk) {
				hql = "from SysRoles";
			} else {
				hql = "from SysRoles where module='" + xtmk + "'";
			}

			List<SysRoles> results = getHibernateTemplate().find(hql);

			return results;

		} catch (RuntimeException re) {

			throw re;
		}
	}

	/**
	 * 根据角色id，得到以权限id为键，"true"为值的Map。
	 * 
	 * @author sparta
	 * @param roleId
	 * @return HashMap<权限ID, true>
	 */
	public HashMap getSelectedPermissionMap(String roleId) {
		try {

			List<String> results = getSession()
					.createSQLQuery(
							"select a.authority_id "
									+ "from sys_authorities a, sys_roles_authorities b "
									+ "where a.authority_id = b.authority_id and b.role_id='"
									+ roleId + "'").list();

			HashMap<String, String> hashMap = new HashMap<String, String>(0);

			for (String authorityId : results) {
				hashMap.put(authorityId, "true");
			}

			return hashMap;
		} catch (RuntimeException re) {

			throw re;
		}
	}

	/*
	 * 保存角色和权限之间一对多的关系。
	 */
	public boolean savePermissionAndRole(String roleId, String[] permisskey) {

		SysRoles sysRoles = findById(roleId);
		SysAuthorities sysAuthorities = null;
		SysRolesAuthorities sysRolesAuthorities;

		// 在重新设置之前先删除之前所拥有的全部对应关系
		sysRolesAuthoritiesDao.deleteOldRoleAndPermissionRelative(roleId);

		try {
			/*
			 * 将用户在前台通过checkbox选中的所有权限id提取出来。 在进行保存之前，首先要通过id提取该权限的实例，
			 * 为角色权限关联表sysRolesAuthorities的setSysAuthorities()提供数据。
			 * 最后通过hibernate的save()方法保存新建的sysRolesAuthorities实例。
			 */
			for (String perId : permisskey) {

				sysAuthorities = sysAuthoritiesDao.findById(perId);

				/*
				 * 生成一个新的实例很重要，否则会报 identifier of an instance of xxx was altered
				 * from xxx to xxx"的异常。
				 */
				sysRolesAuthorities = new SysRolesAuthorities();
				sysRolesAuthorities.setId(Utils.getPkId());
				sysRolesAuthorities.setSysRoles(sysRoles);
				sysRolesAuthorities.setSysAuthorities(sysAuthorities);
				sysRolesAuthorities.setEnabled(true);

				getHibernateTemplate().save(sysRolesAuthorities);

			}

		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}

		return true;
	}

	public List findByExample(SysRoles instance) {
		log.debug("finding SysRoles instance by example");
		try {
			List results = getHibernateTemplate().findByExample(instance);
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findByProperty(String propertyName, Object value) {
		log.debug("finding SysRoles instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from SysRoles as model where model."
					+ propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	public List findByRoleName(Object roleName) {
		return findByProperty(ROLE_NAME, roleName);
	}

	public List findByRoleDesc(Object roleDesc) {
		return findByProperty(ROLE_DESC, roleDesc);
	}

	public List findByEnabled(Object enabled) {
		return findByProperty(ENABLED, enabled);
	}

	public List findByIssys(Object issys) {
		return findByProperty(ISSYS, issys);
	}

	public List findByModule(Object module) {
		return findByProperty(MODULE, module);
	}

	public List findAll() {
		log.debug("finding all SysRoles instances");
		try {
			String queryString = "from SysRoles";
			return getHibernateTemplate().find(queryString);
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

	public SysRoles merge(SysRoles detachedInstance) {
		log.debug("merging SysRoles instance");
		try {
			SysRoles result = (SysRoles) getHibernateTemplate().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public void attachDirty(SysRoles instance) {
		log.debug("attaching dirty SysRoles instance");
		try {
			getHibernateTemplate().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(SysRoles instance) {
		log.debug("attaching clean SysRoles instance");
		try {
			getHibernateTemplate().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public static SysRolesDAO getFromApplicationContext(ApplicationContext ctx) {
		return (SysRolesDAO) ctx.getBean("SysRolesDAO");
	}
}